package com.qf.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.qf.config.AlipayConfig;
import com.qf.feign.api.OrderService;
import com.qf.vo.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Controller
@RequestMapping("/ali")
@Slf4j
public class AliController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/pay")
    public void pay(String oid, HttpServletResponse httpResponse) throws AlipayApiException {
        log.debug("oid:{}", oid);

        // 根据oid查询订单对象
        Order order = orderService.getOrderById(oid);

        log.debug("order:{}", order);

        //1、创建一个客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConfig.gatewayUrl, // 支付网关地址(支付宝网关) https://openapi.alipaydev.com/gateway.do
                AlipayConfig.app_id, // 支付宝分配给开发者的应用ID
                AlipayConfig.merchant_private_key, // 开着自己的私钥
                "json", // 电商品台和支付宝数据交互格式
                AlipayConfig.charset, // 请求使用的编码格式
                AlipayConfig.alipay_public_key, // 支付宝的公钥
                AlipayConfig.sign_type); // 商户生成签名字符串所使用的签名算法类型，目前支持RSA2和RSA，推荐使用RSA2

        // 2、
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url); // 设置支付成功后同步跳转的路径
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url); // 异步通知地址，通知应用用户支付成功了，你要修改订单的状态了

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = oid;
        //付款金额，必填
        Double total_amount = order.getTotalPrice().doubleValue();
        //订单名称，必填
        String subject = order.getSubject();
        //商品描述，可空
        String body = order.getBody();

        String time = "1m";
        // 把支付的参数封装成一个JSON对象
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"timeout_express\":\"" + time + "\"," // 指定支付宝超时时间
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        //输出
        log.debug("result:{}", result);
        try {
            httpResponse.setContentType("text/html;charset=" + AlipayConfig.charset);
            httpResponse.getWriter().write(result); //直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 支付宝是使用POST请求来调用这个解接口
    @PostMapping("/updateOrder")
    public void updateOrder(HttpServletRequest request) {
        log.debug("用户付款成功了，支付宝通知我们修改订单状态了。。。。");

        // 1.创建一个Map
        Map<String, String> paraMap = new HashMap<>();

        // 2.获取ali异步通知的请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            String key = entry.getKey();
            String[] value = entry.getValue();
            log.debug("key:{},value:{}", key, Arrays.toString(value));

            // 把请求的参数全部放到paramMap中
            paraMap.put(key, value[0]);
        }

        try {
            // 3.延签(判断这个请求是支付宝发送的)
            boolean signVerified = AlipaySignature.rsaCheckV1(paraMap,
                    AlipayConfig.alipay_public_key,
                    AlipayConfig.charset,
                    AlipayConfig.sign_type); //调用SDK验证签名
            if (signVerified) {
                log.debug("延签成功");

                // 再次判断订单的id，订单的金额是否一致，支付的状态
                String trade_status = paraMap.get("trade_status");// 获取支付的状态

                // 判断订单额状态是否是支付成功
                if ("TRADE_SUCCESS".equals(trade_status)) {

                    // 获取订单的编号
                    String out_trade_no = paraMap.get("out_trade_no");

                    // 修改的订单的状态
                    orderService.updateOrderStatus(out_trade_no,2);
                    log.debug("修改订单编号");
                }
            } else {
                log.error("延签失败");
            }
        } catch (Exception e) {
            log.error("延签失败出现异常了", paraMap);
        }


    }
}
